/* eslint-disable @typescript-eslint/no-this-alias */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { RouteRecordRaw } from 'vue-router';

// 测试 vitest 用
export function add(a: number, b: number): number {
    return a + b;
}

/**
 * 参数处理
 * @param {*} params  参数
 */
export const tansParams = (params: any) => {
    let result = '';
    for (const propName of Object.keys(params)) {
        const value = params[propName];
        const part = encodeURIComponent(propName) + '=';
        if (
            value !== null &&
            value !== '' &&
            typeof value !== 'undefined'
        ) {
            if (typeof value === 'object') {
                for (const key of Object.keys(value)) {
                    if (
                        value[key] !== null &&
                        value[key] !== '' &&
                        typeof value[key] !== 'undefined'
                    ) {
                        const params =
                            propName + '[' + key + ']';
                        const subPart =
                            encodeURIComponent(params) +
                            '=';
                        result +=
                            subPart +
                            encodeURIComponent(value[key]) +
                            '&';
                    }
                }
            } else {
                result +=
                    part + encodeURIComponent(value) + '&';
            }
        }
    }
    return result;
};

/**
 * 深拷贝
 */
export const deepClone = (source: any) => {
    if (!source && typeof source !== 'object') {
        throw new Error(
            'error arguments',
            'deepClone' as any,
        );
    }
    const targetObj: any =
        source.constructor === Array ? [] : {};
    Object.keys(source).forEach((keys) => {
        if (
            source[keys] &&
            typeof source[keys] === 'object'
        ) {
            targetObj[keys] = deepClone(source[keys]);
        } else {
            targetObj[keys] = source[keys];
        }
    });
    return targetObj;
};

/**
 * @description 扁平化数组对象(主要用来处理路由菜单)
 * @param {Array} menuList 所有菜单列表
 */
export const getFlatArr = (menuList: RouteRecordRaw[]) => {
    const newMenuList = deepClone(menuList);
    return newMenuList.reduce(
        (
            pre: RouteRecordRaw[],
            current: RouteRecordRaw,
        ) => {
            let flatArr = [...pre, current];
            if (current.children)
                flatArr = [
                    ...flatArr,
                    ...getFlatArr(current.children),
                ];
            return flatArr;
        },
        [],
    );
};

// 防抖
export const debounce = (
    func: any,
    wait: number,
    immediate: boolean,
) => {
    let timeout: any,
        args: any,
        context: any,
        timestamp: any,
        result: any;

    const later = function () {
        // 据上一次触发时间间隔
        const last = +new Date() - timestamp;
        // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
        if (last < wait && last > 0) {
            timeout = setTimeout(later, wait - last);
        } else {
            timeout = null;
            // 如果设定为immediate===true，因为开始边界已经调用过了此处无需调用
            if (!immediate) {
                result = func.apply(context, args);
                if (!timeout) context = args = null;
            }
        }
    };
    return (...args: any) => {
        context = this;
        timestamp = +new Date();
        const callNow = immediate && !timeout;
        // 如果延时不存在，重新设定延时
        if (!timeout) timeout = setTimeout(later, wait);
        if (callNow) {
            result = func.apply(context, args);
            context = args = null;
        }
        return result;
    };
};
